#include "platform_config.h"
#include "myjni.h"
#include <pthread.h>
u8  g_ShrowDowntrendIsOk = FALSE;
//u8  g_ShrowUptrendIsOk = FALSE;
u8  g_stateIsShrowDown = FALSE;//抛下粮食标志
u8  g_stateIsPickUp;
int g_distanceFromTopToGrain = MAX_DISTANCE;//粮食到仓顶的距离，单位mm
int g_SurplusDistanceBuff[DISTANCE_BUFF_NUM];
u16 g_loadDistancePosition;
u16 g_grainDecreaseCounter=0;//粮食递减计数器，连续递减10次，判定为抛粮事件发生
u16 g_grainIncreaseCounter=0;//粮食递减计数器，连续递减10次，判定为抛粮事件发生
extern volatile int GPS_MJ_START;
u16 g_minSurplusDistance=MAX_DISTANCE;//最小剩余仓位
u16 g_referGrainHeight = MAX_DISTANCE;//判断抛粮时，用于比对的参考粮食高度

u16 g_filterBuff[FILTER_NUM];
u8  g_logicLevel = LOW_LEVEL;
void LoadDistance(int distance);
int GetStateOfShrowDown(int distance);
int GetMinSurplusDistance(void);
int CheckIfShrowDownInTrend(int distance);
void ClearUltrasonicState(void);
static u8  g_filterCounter = 0;
static int force_report_chanliang = 0;
u16 g_ultrasonicTriggerDelay_ms;//超声波触发周期
u16 g_calculationDistanceDelay_ms=0;//计算周期
//********************************************************************************//
//***函数描述:超声波触发控制(3S触发一次，脉冲宽度2ms)
//***参量描述：
//***返回值描述：
//***作用域描述：ms定时器内(tim4)
//********************************************************************************//
void TriggerUltrasonic(void) {
    //  g_ultrasonicTriggerDelay_ms++;
    //  if(g_ultrasonicTriggerDelay_ms >= TRIGGER_PREIOD )
    //  {

    TRIG_HIGH();
    usleep(30);
    TRIG_LOW();
    //g_ultrasonicTriggerDelay_ms = 0;

    //  }
}


//********************************************************************************//
//***函数描述:存储高度
//***参量描述：
//***返回值描述：
//***作用域描述：
//********************************************************************************//
void LoadDistance(int distance) {
    g_SurplusDistanceBuff[g_loadDistancePosition] = distance;
    if( ++g_loadDistancePosition >= DISTANCE_BUFF_NUM) {
        g_loadDistancePosition = 0;
    }
}

//********************************************************************************//
//***函数描述:得到抛粮状态
//***参量描述：distance 粮仓剩余距离
//***返回值描述：抛粮状态
//***作用域描述：
//********************************************************************************//
int GetStateOfShrowDown(int distance) {
    int stateIsDown = FALSE;
    stateIsDown = CheckIfShrowDownInTrend(distance);//按照趋势判定抛粮操作
    return stateIsDown;
}
//********************************************************************************//
//***函数描述:得到最小剩余高度
//***参量描述：
//***返回值描述：
//***作用域描述：
//********************************************************************************//
int GetMinSurplusDistance(void) {
    u8 i=0;
    int minDistance = g_SurplusDistanceBuff[0];
    for(i=1;i<DISTANCE_BUFF_NUM;i++) {
        if(minDistance > g_SurplusDistanceBuff[i]) {
            minDistance = g_SurplusDistanceBuff[i];
        }
    }
    return minDistance;
}

//********************************************************************************//
//***函数描述:按照趋势判定是否抛粮
//***参量描述：distance 粮仓剩余距离
//***返回值描述：抛粮状态
//***作用域描述：
//********************************************************************************//
/*u8 CheckIfShrowDownInTrend(u16 lastDistance,u16 distance) {
    int diff = distance - lastDistance;
    if(diff > 40) {//高度在增加，抛粮
        if(++g_grainDecreaseCounter > MAX_DESCREASE_COUNTER) {
            if (g_ShrowUptrendIsOk==TRUE) {//粮食只有先增加，然后再减小,才有抛粮动作
                g_ShrowDowntrendIsOk = TRUE;
                g_minSurplusDistance = GetMinSurplusDistance();
            }
        }
        g_grainIncreaseCounter = 0;
    } else if(diff < -20) {//高度在减小，收割
        if(++g_grainIncreaseCounter > MAX_DESCREASE_COUNTER) {
            g_ShrowUptrendIsOk = TRUE; 
        }
        g_grainDecreaseCounter = 0;
    } else {
        g_grainDecreaseCounter = 0;
        g_grainIncreaseCounter = 0;
        LOGE("%s nothing", __func__);
    }
    if(g_ShrowDowntrendIsOk==TRUE && distance>SHROW_DOWN_HEIGHT) {
        return TRUE;
    }
    return FALSE;
}*/
//粮食高度即是最小粮仓剩余高度g_minSurplusDistance，
int CheckIfShrowDownInTrend(int distance) {
    if(distance < g_minSurplusDistance){//若比粮食高度低，说明粮食增加，刷新粮食高度和参考高度；否则说明粮食未增加或减少
        g_minSurplusDistance = distance;
        g_referGrainHeight = distance;
        g_grainDecreaseCounter = 0;
    } else {//如果粮食未增加，判断粮食减少量是否超过限值台阶60mm，采用间断式的比较参考高度，直到超过60mm减少量时，更新参考高高度且递减计数器加1；若计数器超过4，判断抛粮趋势形成
        if(distance > g_referGrainHeight+60 ){
            g_referGrainHeight = distance;
            if(++g_grainDecreaseCounter > MAX_DESCREASE_COUNTER){
                g_ShrowDowntrendIsOk = TRUE;
            }
        }
    }

    if(g_ShrowDowntrendIsOk==TRUE && distance>SHROW_DOWN_HEIGHT) {//一旦趋势形成，等待粮食减少到枯容位（SHROW_DOWN_HEIGHT）时，判断抛粮完成。
        return TRUE;	
    }
    return FALSE;
}

void read_g_minSurplusDistance(void) {//用户有时候按下亩数计算才抛粮，所以无需趋势判断
    char buf[48] = {0};
    force_report_chanliang = 1;
    sprintf(buf,"$Height:%d\r\n", g_minSurplusDistance);
    LOGE("$H:%d;$D:%d", g_distanceFromTopToGrain, g_stateIsShrowDown);
    jniToJava(buf, strlen(buf));
    ClearUltrasonicState();

}

//********************************************************************************//
//***函数描述:清除超声波状态
//***参量描述：
//***返回值描述：
//***作用域描述：主循环
//********************************************************************************//
void ClearUltrasonicState(void)
{
    g_minSurplusDistance = MAX_DISTANCE ;
    g_referGrainHeight = MAX_DISTANCE ;
    g_grainDecreaseCounter = 0;
    g_ShrowDowntrendIsOk = FALSE;
    //g_ShrowUptrendIsOk = FALSE;
    g_stateIsShrowDown = FALSE;
    g_loadDistancePosition =0;
    memset(g_SurplusDistanceBuff,MAX_DISTANCE,sizeof(g_SurplusDistanceBuff));

}
//********************************************************************************//
//***函数描述：得到超声波发送到接收的延时时间
//***参量描述：无
//***返回值描述：延时时间;单位us
//***作用域描述：边沿触发
//********************************************************************************//
int GetDelayOfUltrasonic(void)
{
    return readUltra();
}
//********************************************************************************//
//***函数描述：递推滤波
//***参量描述：1、value:实时值；2、滤波次数
//***返回值描述：滤波后的值
//***作用域描述：
//********************************************************************************//
#if 0
u16 Filter(u16 value,u16 numOfFilter)
{
    u8 i=0;
    u32 sum=0;
    if(g_filterCounter >= numOfFilter)
    {
        for(i=0;i<numOfFilter-1;i++)
        {
            g_filterBuff[i] = g_filterBuff[i+1];
            sum += g_filterBuff[i];
        }
        g_filterBuff[numOfFilter-1] = value;
        sum += g_filterBuff[numOfFilter-1];
    }
    else
    {
        g_filterBuff[g_filterCounter] = value;
        for(i=0;i<g_filterCounter+1;i++)
        {
            sum += g_filterBuff[g_filterCounter];
        }
        g_filterCounter ++;
    }

    return (sum/g_filterCounter);
}
#endif
